﻿using System;

namespace Patterns.Adapter {

    public class AppliedExample {

        public static void Run() {
            // Non-adapted chemical compound
            Compound stuff = new Compound("Unknown");
            stuff.Display();

            // Adapted chemical compounds
            Compound water = new RichCompound("Water");
            water.Display();

            Compound benzene = new RichCompound("Benzene");
            benzene.Display();

            Compound alcohol = new RichCompound("Alcohol");
            alcohol.Display();
        }

        // "Target"
        private class Compound {
            protected string Name { get; set; }
            protected float BoilingPoint { get; set; }
            protected float MeltingPoint { get; set; }
            protected double MolecularWeight { get; set; }
            protected string MolecularFormula { get; set; }

            // Constructor
            public Compound(string name) {
                Name = name;
            }

            public virtual void Display() {
                Console.WriteLine("\nCompound: {0} ------ ", Name);
            }
        }

        // "Adapter"
        private class RichCompound : Compound {
            private ChemicalDatabank Bank { get; set; }

            // Constructor
            public RichCompound(string name)
                : base(name) { }

            public override void Display() {
                // Adaptee
                Bank = new ChemicalDatabank();
                BoilingPoint = Bank.GetCriticalPoint(Name, "B");
                MeltingPoint = Bank.GetCriticalPoint(Name, "M");
                MolecularWeight = Bank.GetMolecularWeight(Name);
                MolecularFormula = Bank.GetMolecularStructure(Name);

                base.Display();
                Console.WriteLine(" Formula: {0}", MolecularFormula);
                Console.WriteLine(" Weight : {0}", MolecularWeight);
                Console.WriteLine(" Melting Pt: {0}", MeltingPoint);
                Console.WriteLine(" Boiling Pt: {0}", BoilingPoint);
            }
        }

        // "Adaptee"
        private class ChemicalDatabank {
            // The Databank 'legacy API'
            public float GetCriticalPoint(string compound, string point) {
                float temperature = 0.0F;
                // Melting Point
                if (point == "M") {
                    switch (compound.ToLower()) {
                        case "water": temperature = 0.0F; break;
                        case "benzene": temperature = 5.5F; break;
                        case "alcohol": temperature = -114.1F; break;
                    }
                }
                // Boiling Point
                else {
                    switch (compound.ToLower()) {
                        case "water": temperature = 100.0F; break;
                        case "benzene": temperature = 80.1F; break;
                        case "alcohol": temperature = 78.3F; break;
                    }
                }
                return temperature;
            }

            public string GetMolecularStructure(string compound) {
                string structure = "";
                switch (compound.ToLower()) {
                    case "water": structure = "H20"; break;
                    case "benzene": structure = "C6H6"; break;
                    case "alcohol": structure = "C2H6O2"; break;
                }
                return structure;
            }

            public double GetMolecularWeight(string compound) {
                double weight = 0.0;
                switch (compound.ToLower()) {
                    case "water": weight = 18.015; break;
                    case "benzene": weight = 78.1134; break;
                    case "alcohol": weight = 46.0688; break;
                }
                return weight;
            }
        }
    }
}
